﻿using System;
using System.Windows.Forms;
using G.Model;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.XmlEditor;

namespace GameSharpAddin
{
    public class GameView : 
       AbstractSecondaryViewContent,
       IHasPropertyContainer, IDisposable
    {
        private readonly PropertyContainer _PropertyContainer;
        private readonly GamePanel _Panel;
        
        private GameSpaceDef _GameDef;
        private bool ignoreDirtyChange;
        
        public GameView(IViewContent viewContent) : base(viewContent)
        {
            TabPageText = "Design";
            _PropertyContainer = new PropertyContainer();
            
            _GameDef = new GameSpaceDef();
            _GameDef.DirtyChanged += OnDirtyChanged;
            _Panel = new GamePanel(_GameDef);
            _Panel.BoardControl.GameDisplayer.ActiveObject.SelectedEvent += OnSelectedEvent; 
            _Panel.BoardControl.GameChangedEvent += OnGameChanged;
        }
        
        private void OnGameChanged(GameSpaceDef pGameDef)
        {
            if (_GameDef != null)
            {
                _GameDef.DirtyChanged -= OnDirtyChanged;
            }
            _GameDef = pGameDef;
            _GameDef.DirtyChanged += OnDirtyChanged;
        }
        
        private void OnDirtyChanged(object source, EventArgs e)
        {
            if (!ignoreDirtyChange) 
            {
                this.PrimaryFile.IsDirty = _Panel.BoardControl.GameDef.IsDirty;
            }
        }
        
        private void OnSelectedEvent(object obj)
        {
            _PropertyContainer.SelectedObject = obj;
        }
        
        public override void Dispose()
        {
            base.Dispose();
            _Panel.BoardControl.GameDisplayer.ActiveObject.SelectedEvent -= OnSelectedEvent; 
        }
        
        public override object Control 
        {
            get { return _Panel; }
        }

        public PropertyContainer PropertyContainer
        { 
            get { return _PropertyContainer;}
        }

        public GamePanel GameTreePanel
        {
            get { return _Panel; }
        }
        
        protected override void LoadFromPrimary()
        {
            try 
            {
                IFileDocumentProvider provider = this.PrimaryViewContent as IFileDocumentProvider;
                IDocument document = provider.GetDocumentForFile(this.PrimaryFile);
                
                GameSpaceDef game = GameSpaceDef.Load(document.Text);
                _Panel.BoardControl.GameDef = game;
                _Panel.BoardControl.GameDisplayer.ActiveObject.SelectedEvent += OnSelectedEvent; 
                
                XmlView view = XmlView.ForFile(this.PrimaryFile);
                if (view != null) {
                    XmlView.CheckIsWellFormed(view.TextEditor);
                }
            }
            catch (Exception e) {
                ICSharpCode.Core.MessageService.ShowException(e);
            }
        }
        
        protected override void SaveToPrimary()
        {
            try
            {
                if (_Panel.BoardControl.GameDef.IsDirty)
                {
                    XmlView view = XmlView.ForFile(this.PrimaryFile);
                    if (view != null) {
                        string xml = _Panel.BoardControl.GameDef.Xml;
                        XmlView.ReplaceAll(xml, view.TextEditor);
                        ignoreDirtyChange = true;
                        _Panel.BoardControl.GameDef.IsDirty = false;
                        ignoreDirtyChange = false;
                    }
                }
            }
            catch (Exception e) {
                ICSharpCode.Core.MessageService.ShowException(e);
            }
        }
        
        public override bool IsViewOnly {
            get { return true; }
        }
    }
}
